package pl.edu.uj.tcs.blef.utils;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.TreeSet;

import pl.edu.uj.tcs.blef.server.Client;

public final class BetPool {
	private TreeSet<Bet> bets;
	private LinkedList<Client> clients;
	
	public BetPool(){
		this.bets = new TreeSet<Bet>();
		this.clients = new LinkedList<Client>();
	}
	
	public boolean newBet(Client client, Bet bet){
		if(bets.size() == 0){
			bets.add(bet);
			clients.add(client);
			return true;
		} else if(bets.last().compareTo(bet) == -1) {
			bets.add(bet);
			clients.add(client);
			return true;
		} else return false;
	}
	
	public int size(){
		return bets.size();
	}
	
	public Client getLastPlayer(){
		return clients.getLast();
	}
	
	public boolean check(LinkedList<Card> cards){
		try {
			HighCard bet = (HighCard)bets.last();
			if(cards.contains(bet.getCard())) return true;
			else return false;
		}catch (ClassCastException e){}
		
		try {
			Pair bet = (Pair)bets.last();
			int occurences = 0;
			for(Card c: cards){
				if(c.equals(bet.getCard())) occurences++;
			}
			
			if(occurences >= 2) return true;
			else return false;
		}catch (ClassCastException e){}
		
		try {
			TwoPairs bet = (TwoPairs)bets.last();
			int occurencesFirst = 0;
			int occurencesSecond = 0;
			for(Card c: cards){
				if(c.equals(bet.getFirst())) occurencesFirst++;
				if(c.equals(bet.getSecond())) occurencesSecond++;
			}
			
			if(occurencesFirst >= 2 && occurencesSecond >= 2) return true;
			else return false;
		}catch (ClassCastException e){}
		
		try {
			Three bet = (Three)bets.last();
			int occurences = 0;
			for(Card c: cards){
				if(c.equals(bet.getCard())) occurences++;
			}
			
			if(occurences >= 3) return true;
			else return false;
		}catch (ClassCastException e){}
		
		try {
			Full bet = (Full)bets.last();
			int occurencesFirst = 0;
			int occurencesSecond = 0;
			for(Card c: cards){
				if(c.equals(bet.getFirst())) occurencesFirst++;
				if(c.equals(bet.getSecond())) occurencesSecond++;
			}
			
			if(occurencesFirst >= 3 && occurencesSecond >= 2) return true;
			else return false;
		}catch (ClassCastException e){}
		
		try {
			ColorBet bet = (ColorBet)bets.last();
			int occurences = 0;
			for(Card c: cards){
				if(c.getColor().equals(bet.getColor())) occurences++;
			}
			
			if(occurences >= 5) return true;
			else return false;
		}catch (ClassCastException e){}
		
		try {
			Four bet = (Four)bets.last();
			int occurences = 0;
			for(Card c: cards){
				if(c.equals(bet.getCard())) occurences++;
			}
			
			if(occurences >= 4) return true;
			else return false;
		}catch (ClassCastException e){}
		
		try {
			StraightFlush bet = (StraightFlush)bets.last();
			int occurences = 0;
			for(Card c: cards){
				if(c.equals(bet.getColor()) && c.equals(new Nine(bet.getColor()))) occurences++;
				if(c.equals(bet.getColor()) && c.equals(new Ten(bet.getColor()))) occurences++;
				if(c.equals(bet.getColor()) && c.equals(new Jack(bet.getColor()))) occurences++;
				if(c.equals(bet.getColor()) && c.equals(new Queen(bet.getColor()))) occurences++;
				if(c.equals(bet.getColor()) && c.equals(new King(bet.getColor()))) occurences++;
			}
			
			if(occurences >= 5) return true;
			else return false;
			
		}catch (ClassCastException e){}
		
		try {
			RoyalFlush bet = (RoyalFlush)bets.last();
			int occurences = 0;
			for(Card c: cards){
				if(c.equals(bet.getColor()) && c.equals(new Ten(bet.getColor()))) occurences++;
				if(c.equals(bet.getColor()) && c.equals(new Jack(bet.getColor()))) occurences++;
				if(c.equals(bet.getColor()) && c.equals(new Queen(bet.getColor()))) occurences++;
				if(c.equals(bet.getColor()) && c.equals(new King(bet.getColor()))) occurences++;
				if(c.equals(bet.getColor()) && c.equals(new Ace(bet.getColor()))) occurences++;
			}
			
			if(occurences >= 5) return true;
			else return false;
			
		}catch (ClassCastException e){}
		
		return false;
	}
	
	@Override
	public String toString(){
		int i = 0; StringBuilder sb = new StringBuilder();
		sb.append("BETS: " + bets.size()); sb.append('\n');
		Iterator<Bet> it = bets.descendingIterator();
		while(it.hasNext()){
			sb.append(clients.get(i).getNick() + " " + it.next().getCode());
			sb.append('\n');
		}
		
		return sb.toString().trim();
	}
}
